package top.zlcode.friend.manager;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.zlcode.common.core.constants.CacheConstants;
import top.zlcode.common.core.enums.ResultCode;
import top.zlcode.common.redis.service.RedisService;
import top.zlcode.common.security.exception.ServiceException;
import top.zlcode.friend.domain.question.Question;
import top.zlcode.friend.domain.question.vo.QuestionAnalysisVO;
import top.zlcode.friend.domain.question.vo.QuestionCodeSuggestVO;
import top.zlcode.friend.mapper.question.QuestionMapper;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class QuestionCacheManager {

    @Autowired
    private RedisService redisService;

    @Autowired
    private QuestionMapper questionMapper;

    public Long getListSize() {
        return redisService.getListSize(CacheConstants.QUESTION_LIST);
    }

    public Long getHostListSize() {
        return redisService.getListSize(CacheConstants.QUESTION_HOST_LIST);
    }

    public void refreshCache() {
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<Question>()
                .select(Question::getQuestionId).orderByDesc(Question::getCreateTime));
        if (CollectionUtil.isEmpty(questionList)) {
            return;
        }
        List<Long> questionIdList = questionList.stream().map(Question::getQuestionId).toList();
        redisService.rightPushAll(CacheConstants.QUESTION_LIST, questionIdList);
    }

    public Long preQuestion(Long questionId) {
        Long index = redisService.indexOfForList(CacheConstants.QUESTION_LIST, questionId);
        if (index == 0) {
            throw new ServiceException(ResultCode.QUESTION_FAILED_FIRST_QUESTION);
        }
        return redisService.indexForList(CacheConstants.QUESTION_LIST, index - 1, Long.class);
    }

    public Object nextQuestion(Long questionId) {
        Long index = redisService.indexOfForList(CacheConstants.QUESTION_LIST, questionId);
        long lastIndex = getListSize() - 1;
        if (index == lastIndex) {
            throw new ServiceException(ResultCode.QUESTION_FAILED_LAST_QUESTION);
        }
        return redisService.indexForList(CacheConstants.QUESTION_LIST, index + 1, Long.class);
    }

    public List<Long> getHostList() {
        return redisService.getCacheListByRange(CacheConstants.QUESTION_HOST_LIST,
                CacheConstants.DEFAULT_START, CacheConstants.DEFAULT_END, Long.class);
    }

    public void refreshHotQuestionList(List<Long> hotQuestionIdList) {
        if (CollectionUtil.isEmpty(hotQuestionIdList)) {
            return;
        }
        redisService.rightPushAll(CacheConstants.QUESTION_HOST_LIST, hotQuestionIdList);
    }

    public QuestionAnalysisVO getAnalysis(Long questionId) {
        return redisService.getCacheObject(getAnalysisKey(questionId), QuestionAnalysisVO.class);
    }

    public void setAnalysis(QuestionAnalysisVO analysisVO) {
        redisService.setCacheObject(getAnalysisKey(analysisVO.getQuestionId()), analysisVO);
    }

    /**
     * 设置用户提交代码 ai 建议优化缓存
     */
    public void setCodeSuggest(Long userId, Long questionId, String uuid, QuestionCodeSuggestVO questionCodeSuggestVO) {
        String key = getCodeSuggestKey(userId, questionId, uuid);
        redisService.setCacheObject(key, questionCodeSuggestVO, CacheConstants.QUESTION_CODE_SUGGEST_EXPIRE_TIME, TimeUnit.DAYS);
    }

    /**
     * 获取指定用户这次提交记录的代码建议优化的信息
     */
    public QuestionCodeSuggestVO getCodeSuggest(Long userId, Long questionId, String uuid) {
        String key = getCodeSuggestKey(userId, questionId, uuid);
        return redisService.getCacheObject(key, QuestionCodeSuggestVO.class);
    }

    private String getAnalysisKey(Long questionId) {
        return CacheConstants.QUESTION_ANALYSIS_KEY + questionId;
    }

    private String getCodeSuggestKey(Long userId, Long questionId, String uuid) {
        return CacheConstants.QUESTION_CODE_SUGGEST_KEY + userId + ":" + questionId + ":" + uuid;
    }
}
